/*
 earth.js
 Austin Abrams, Washington University in St. Louis
 1/7/2010
 
 A set of scripts that helps to abstract away some Google Earth Plugin details from Live3D.
 */

var ge = null;

google.load("earth", "1");
google.load("maps", "2");

// initializes Google Earth plugin.
function googleInit( name ) {
	if ( typeof(name) == 'undefined' ) {
		google.earth.createInstance("map3d", initCB, failureCB);
	} else {
		google.earth.createInstance(name, initCB, failureCB);
	}
}

// the callback function from the initialization function.
// notice that this function always calls init(), which is to be
// defined in another file or the HTML document itself.  init()
// will be called once the Google Earth plugin loads.
function initCB( object ) {
	ge = object;
	ge.getWindow().setVisibility(true);
	ge.getOptions().setStatusBarVisibility(true);
	ge.getOptions().setBuildingHighlightingEnabled(true);
	var navControl = ge.getNavigationControl();
	navControl.setVisibility(ge.VISIBILITY_SHOW);

	ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, true);
	ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, true);
	
	toggleGrayBuildings();
	toggleBuildings();
	
	ge.getOptions().setUnitsFeetMiles(false);
	
	init3D();
	//setTimeout(function() { init3D(); }, 500);
}

// a failure callback function.
function failureCB( object ) {
	document.getElementById("error").innerHTML += "Failed to load Google Earth Plugin.";
}

//************UI STUFF*********************
// turns the gray buildings on or off.
function toggleGrayBuildings() {
	if ( document.getElementById('showGrayBuildings') ) {
		var checked = document.getElementById('showGrayBuildings').checked;
		ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS_LOW_RESOLUTION, checked);
	} else {
		ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS_LOW_RESOLUTION, true);
	}
}

// turns the textured buildings on or off.
function toggleBuildings() {
	if (document.getElementById('showGrayBuildings')){
		var checked = document.getElementById('showBuildings').checked;
		ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, checked);
	} else {
		ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, true);
	}
}
var speed=100;

//increase or decrease the amount by which you move up and down
function changeSpeed() {
	var text=document.getElementById('spee');
	speed=text.value;
}

// increases or decreases the camera height by *speed* meters at the push of a button
function changeAlt( option ) {
	// Get the current view
	var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND);
	var x;
	if(option.localeCompare('increase')){
		x=camera.getAltitude() + parseFloat(speed);
		camera.setAltitude(x); // move up
	}
	
	else if(option.localeCompare('decrease')){
		x=camera.getAltitude() - parseFloat(speed);
		camera.setAltitude(x); // move down
	}
	
	// Update the view in Google Earth
	ge.getView().setAbstractView(camera);
}

// switch between metric units
function toggleUnits() {
	if(document.visualize.units[0].checked)
		ge.getOptions().setUnitsFeetMiles(false);
	else
		ge.getOptions().setUnitsFeetMiles(true);
}

//enable or disable the sun 
function toggleSun() {
	if (document.getElementById('showSun').checked){
		ge.getSun().setVisibility(true);
	}
	else {
		ge.getSun().setVisibility(false);
	}
}

//enable or disable the atmosphere
function toggleAtm() {
	if (document.getElementById('showAtm').checked){
		ge.getOptions().setAtmosphereVisibility(false);
	}
	else {
		ge.getOptions().setAtmosphereVisibility(true);
	}
}

// From http://earth-api-samples.googlecode.com/svn/trunk/demos/milktruck/index.html
function submitLocation() {
	var searchString = document.getElementById('address').value;
	var overlaySearchString = document.getElementById('locationSearchOverlay').value;

	var finalSearchString = searchString == "" ? overlaySearchString : searchString;

	doGeocode(finalSearchString);
}

// given some search string, this jumps to the destination.
// the search is localized, so that if you search for 'lopata' around STL,
// it won't send you into Eastern Europe when you really want
// 'lopata hall in washington university in st louis'
function doGeocode( address ) {
	var geocoder = new GClientGeocoder();
	var globeBounds = ge.getView().getViewportGlobeBounds();
	var sw = new GLatLng(globeBounds.getSouth(), globeBounds.getWest());
	var ne = new GLatLng(globeBounds.getNorth(), globeBounds.getEast());

	var bounds = new GLatLngBounds(sw, ne);

	geocoder.setViewport(bounds);
	geocoder.getLatLng(address, function(point) {
		if (point) {
			jumpTo(point.y, point.x);
			if (typeof(build3D) != 'undefined'){
				setTimeout('build3D.polygon.buildInCenter();', 2000);
			}
		}
	});
}

// moves the camera to the latitude and longitude specified.
function jumpTo( lat, lon ) {
	var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
	lookAt.setLatitude(lat);
	lookAt.setLongitude(lon);
	lookAt.setRange(300);
	
	ge.getView().setAbstractView(lookAt);
}

// to prevent awkward motions (bouncing and camera tilting while still moving
// to a location) and to make it more clear to the user where they're traveling
// before the camera starts doing weird things, the initial jumpToFull will
// go to a lat lon location and THEN change camera angles
function initJumpToFull( lat, lon, alt, roll, tilt, heading ) { 
	if ( alt == 0 ) alt = 1000; // default altitude
	var viewChangeEventHandler = function() {
		google.earth.removeEventListener(ge.getView(), 'viewchangeend', viewChangeEventHandler);
		setTimeout(function() { 
			jumpToFull(lat, lon, alt, roll, tilt, heading);
		}, 300);
	}

	google.earth.addEventListener(ge.getView(), 'viewchangeend', viewChangeEventHandler);

	jumpTo(lat, lon);
}

// moves the camera to the latitude, longitude, altitude, roll, tilt, and heading.
function jumpToFull( lat, lon, alt, roll, tilt, heading ) {
	var cam = ge.getView().copyAsCamera(ge.ALTITUDE_ABSOLUTE);
	cam.setLatitude(lat);
	cam.setLongitude(lon);
	cam.setAltitude(alt);
	cam.setRoll(roll);
	cam.setTilt(tilt);
	cam.setHeading(heading);
	ge.getView().setAbstractView(cam);
}

function absoluteHitTestPercent( percentX, percentY ) {
	var hitTestBuilding = ge.getView().hitTest( percentX, ge.UNITS_FRACTION, percentY, ge.UNITS_FRACTION, ge.HIT_TEST_BUILDINGS );
	var hitTestTerrain = ge.getView().hitTest( percentX, ge.UNITS_FRACTION, percentY, ge.UNITS_FRACTION, ge.HIT_TEST_TERRAIN );
	var hitTestGlobe = ge.getView().hitTest( percentX, ge.UNITS_FRACTION,percentY, ge.UNITS_FRACTION, ge.HIT_TEST_GLOBE );
	
	return absoluteHitTest( hitTestBuilding, hitTestTerrain, hitTestGlobe );
}

function absoluteHitTestPixels( pixelsX, pixelsY ) {
	var hitTestBuilding = ge.getView().hitTest(pixelsX, ge.UNITS_PIXELS, pixelsY, ge.UNITS_PIXELS, ge.HIT_TEST_BUILDINGS);
	var hitTestTerrain = ge.getView().hitTest(pixelsX, ge.UNITS_PIXELS,pixelsY, ge.UNITS_PIXELS, ge.HIT_TEST_TERRAIN);
	var hitTestGlobe = ge.getView().hitTest(pixelsX, ge.UNITS_PIXELS,pixelsY, ge.UNITS_PIXELS, ge.HIT_TEST_GLOBE);
	
	return absoluteHitTest(hitTestBuilding, hitTestTerrain, hitTestGlobe);
}

// a test to see if a given x,y coordinate is touching a building
function hitTestPixelsIsBuilding( pixelsX, pixelsY ) {
	var hitTestBuilding = ge.getView().hitTest(pixelsX, ge.UNITS_PIXELS, pixelsY, ge.UNITS_PIXELS, ge.HIT_TEST_BUILDINGS);

	return (hitTestBuilding != null);
}

function absoluteHitTest( hitTestBuilding, hitTestTerrain, hitTestGlobe ) {
	var hitTest = null;
	if ( hitTestBuilding ) {
		hitTest = hitTestBuilding;
	} else if ( hitTestTerrain ) {
		hitTest = hitTestTerrain;
	} else if ( hitTestGlobe ) {
		hitTest = hitTestGlobe;
	} else {
		return null;
	}
	var lon = hitTest.getLongitude();
	var lat = hitTest.getLatitude();
	var alt = hitTest.getAltitude();

	if ( alt < ge.getGlobe().getGroundAltitude( lat, lon ) ) {
		alt = ge.getGlobe().getGroundAltitude( lat, lon );
	}

	return { lat:lat, lon:lon, alt:alt };
}